﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace SmartLib.Reflection
{
    internal class TypeReflection : IEnumerable<PropertyReflection>
    {
        private Type _type;
        private Dictionary<string,PropertyReflection> _propertyCache;
        private string _tableName;
        private Dynamic.DynamicConstructor.InvokeConstructor _invokeContructor;

        public TypeReflection(Type type)
        {
            Utils.AssertUtils.IsNotNull(type, "type不能为空");
            _type = type;
            _propertyCache = new Dictionary<string, PropertyReflection>();

            PopulateProperties();

            InitAttributes();

            _invokeContructor = Dynamic.DynamicConstructor.CompileConstructor(type);
        }

        private void PopulateProperties()
        {
            PropertyInfo[] propertyInfos = _type.GetProperties();

            foreach (var propertyInfo in propertyInfos)
            {
                PropertyReflection pf = new PropertyReflection(propertyInfo);

                _propertyCache.Add(pf.ColumnName.ToLower(), pf);
            }
        }

        private void InitAttributes()
        {
            Attribute[] attrs = _type.GetCustomAttributes(true) as Attribute[];

            if (attrs != null)
            {
                foreach (var attr in attrs)
                {
                    if (attr is Attributes.TableAttribute)
                    {
                        _tableName = ((Attributes.TableAttribute)attr).TableName;
                    }
                }
            }

            if (string.IsNullOrEmpty(_tableName)) _tableName = _type.Name;
        }

        public PropertyReflection this[string propertyName]
        {
            get
            {
                if (_propertyCache.ContainsKey(propertyName.ToLower()))
                {
                    return _propertyCache[propertyName.ToLower()];
                }
                return null;
            }
        }

        /// <summary>
        /// 创建类型实例
        /// </summary>
        /// <returns></returns>
        public object NewInstance()
        {
            return _invokeContructor();
        }

        #region IEnumerable<PropertyReflection> 成员

        public IEnumerator<PropertyReflection> GetEnumerator()
        {
            return _propertyCache.Values.GetEnumerator();
        }

        #endregion

        #region IEnumerable 成员

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _propertyCache.Values.GetEnumerator();
        }

        #endregion
    }
}
